package com.example.composite.Impi;

import com.example.composite.Employee;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class ManagerImpi implements Employee {
    private String name;
    private String position;
    private List<Employee> employees = Collections.synchronizedList(new LinkedList<Employee>());

    public ManagerImpi(String name, String position) {
        this.name = name;
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public String getPosition() {
        return position;
    }

    @Override
    public void showDetails() {
        System.out.println("Name: " + name + " Position: " + position + " Employees: " + employees);
    }

    @Override
    public void add(Employee employee) {
        employees.add(employee);
    }

    @Override
    public void remove(Employee employee) {
        employees.remove(employee);
    }

    /**
     * 广度优先遍历
     * @param target
     * @return
     */
    public Employee findEmployeeByBFS(Employee target) {
        LinkedList<Employee> queue = new LinkedList<>();

        queue.add(this);
        while (!queue.isEmpty()) {
            Employee employee = queue.poll();
            if (employee instanceof ManagerImpi) {
                ManagerImpi managerImpi = (ManagerImpi) employee;
                for (Employee emp : managerImpi.employees) {
                    if (emp == target) {
                        return emp;
                    }
                    queue.add(emp);
                }
            }
        }
        return null;
    }

    /**
     * 深度优先遍历
     * @param target
     * @return
     */
    public Employee findEmployeeByDFS(Employee target) {
        for (Employee employee : employees) {
            if (employee == target) {
                return employee;
            }
            if (employee instanceof ManagerImpi) {
                Employee t = ((ManagerImpi) employee).findEmployeeByDFS(target);
                if (t != null) {
                    return t;
                }
            }
        }
        return null;
    }
}
